class TaskPro {
  taskList = [];
  currentIndex = 0;
  isRunning = false;
  addTask(task) {
    this.taskList.push(task);
  }
  async run() {
    if (this.isRunning) {
      return;
    }
    this.isRunning = true;
    await this.runNextTask();
  }
  runNextTask = async () => {
    if (this.taskList.length === 0) {
      this.isRunning = false;
      return;
    }
    const task = this.taskList.shift();
    let hasRunNext = false;
    await task(() => {
      hasRunNext = true;
      return this.runNextTask();
    });
    if (!hasRunNext) {
      await this.runNextTask();
    }
  }
}
class TaskProCircle {
  taskList = [];
  currentIndex = 0;
  isRunning = false;
  addTask(task) {
    this.taskList.push(task);
  }
  async run() {
    if (this.isRunning) {
      return;
    }
    this.isRunning = true;
    this.currentIndex = 0;
    await this.runNextTask();
  }
  runNextTask = async () => {
    if (this.currentIndex >= this.taskList.length) {
      this.isRunning = false;
      return;
    }
    const task = this.taskList[this.currentIndex++];
    let hasRunNext = false;
    await task(() => {
      hasRunNext = true;
      return this.runNextTask();
    });
    if (!hasRunNext) {
      await this.runNextTask();
    }
  };
}

const t = new TaskPro();
t.addTask(async (next) => {
  console.log('task1 start');
  await next();
  console.log('task1 end');
});
t.addTask((next) => {
  console.log('task2');
});
t.addTask((next) => {
  console.log('task3');
});
t.run()
//task1 start
task2task3 task1 end